package com.example.homework.ui

import android.Manifest
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.example.homework.App
import com.example.homework.MainActivity
import com.example.homework.R
import com.example.homework.adapters.PhotosRecyclerViewAdapter
import com.example.homework.databinding.FragmentGalleryBinding
import com.example.homework.repositories.PhotoRepository
import com.example.homework.viewmodels.PhotoViewModel
import com.example.homework.viewmodels.PhotoViewModelFactory
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.messaging.FirebaseMessaging
import kotlinx.coroutines.launch
import kotlin.random.Random

class GalleryFragment : Fragment() {
    private val viewModel: PhotoViewModel by activityViewModels<PhotoViewModel>() {
        PhotoViewModelFactory(PhotoRepository((requireActivity().application as App).db.photoDao()))
    }
    private var _binding: FragmentGalleryBinding? = null
    private val binding: FragmentGalleryBinding
        get() = _binding!!

    private val launcher: ActivityResultLauncher<Array<String>> =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { map ->
            if (!map.values.all { it }) {
                Toast.makeText(requireContext(), "Permission is not granted", Toast.LENGTH_LONG)
                    .show()
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentGalleryBinding.inflate(inflater, container, false)
        checkPermission()
        binding.showNotificationButton.setOnClickListener {
            createNotification()
        }
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val photoAdapter: PhotosRecyclerViewAdapter = PhotosRecyclerViewAdapter()
        binding.photosRecyclerView.adapter = photoAdapter
        binding.showCameraFragmentButton.setOnClickListener {
            try {
                FirebaseCrashlytics.getInstance().log("Catching my custom exception")
                throw Exception("Custom exception to check crashlytics")
            } catch (e: Exception) {
                FirebaseCrashlytics.getInstance().recordException(e)
            }
            findNavController().navigate(R.id.action_galleryFragment_to_cameraFragment)
        }
        viewLifecycleOwner.lifecycleScope.launch {
            viewModel.photos.collect {
                photoAdapter.submitList(it)
            }
        }
        FirebaseMessaging.getInstance().token.addOnCompleteListener {
            Log.d(LOG_TOKEN_ID, it.result)
        }
    }


    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    @RequiresPermission(Manifest.permission.POST_NOTIFICATIONS)
    fun createNotification() {
        val intent = Intent(requireContext(), MainActivity::class.java)
        val pendingIntent =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
                PendingIntent.getActivity(
                    requireContext(),
                    0,
                    intent,
                    PendingIntent.FLAG_IMMUTABLE
                )
            else
                PendingIntent.getActivity(
                    requireContext(),
                    0,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
        val notification = NotificationCompat.Builder(requireContext(), App.NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(android.R.drawable.ic_notification_overlay)
            .setContentTitle("Homework app notification")
            .setContentText("Description")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()
        NotificationManagerCompat.from(requireContext()).notify(Random.nextInt(), notification)
    }

    private fun checkPermission() {
        val isAllGranted = REQUEST_PERMISSIONS.all { permission ->
            ContextCompat.checkSelfPermission(
                requireContext(),
                permission
            ) == PackageManager.PERMISSION_GRANTED
        }
        if (!isAllGranted) {
            launcher.launch(REQUEST_PERMISSIONS)
        }
    }

    companion object {
        private val REQUEST_PERMISSIONS: Array<String> = buildList {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                add(android.Manifest.permission.POST_NOTIFICATIONS)
            }
        }.toTypedArray()
        private val LOG_TOKEN_ID = "fcm_token"
    }
}